﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Globalization;

namespace PersonalAlbum
{
    public class ThemeViewEngine : WebFormViewEngine
    {
        public ThemeViewEngine()
        {
            base.ViewLocationFormats = new string[] {
            "~/Views/{1}/{0}.aspx",
            "~/Views/{1}/{0}.ascx",
            "~/Views/Shared/{0}.aspx",
            "~/Views/Shared/{0}.ascx"
        };

            base.MasterLocationFormats = new string[] {
            "~/Content/Themes/{2}/Site.master",
            "~/Views/Shared/Site.master"
        };

            base.PartialViewLocationFormats = new string[] {
                "~/Views/Shared/{0}.ascx",
            "~/Views/{1}/{0}.ascx",
            "~/Views/{1}/{0}.aspx",
            "~/Views/Shared/{0}.aspx",
            "~/Views/Shared/Extensions/{0}.ascx"
        };
        }

        public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
        {
            try
            {
                if (controllerContext == null)
                {
                    throw new ArgumentNullException("controllerContext");
                }
                if (string.IsNullOrEmpty(viewName))
                {
                    throw new ArgumentException("Value is required.", "viewName");
                }

                string themeName = this.GetThemeToUse(controllerContext);

                string[] searchedViewLocations = null;
                string[] searchedMasterLocations=null;

                string controllerName =
                  controllerContext.RouteData.GetRequiredString("controller");

                string viewPath = null;
                if (controllerContext.HttpContext.Request.Browser.IsMobileDevice)
                {
                    viewPath = this.GetMobileViewPath(this.ViewLocationFormats, viewName,
                                      controllerName, out searchedViewLocations);
                }
                if (viewPath == null)
                {
                    viewPath = this.GetViewPath(this.ViewLocationFormats, viewName,
                                      controllerName, out searchedViewLocations);
                }
                string masterPath=null ;
                if (controllerContext.HttpContext.Request.Browser.IsMobileDevice)
                {
                    masterPath = this.GetMasterPath(this.MasterLocationFormats, viewName,
                                   controllerName, "Mobile", out searchedMasterLocations);
                }
                if (masterPath==null)
                {
                    masterPath = this.GetMasterPath(this.MasterLocationFormats, viewName,
                                    controllerName, themeName, out searchedMasterLocations);
                }

                if (!(string.IsNullOrEmpty(viewPath)) &&
                   (!(masterPath == string.Empty) || string.IsNullOrEmpty(masterName)))
                {
                    return new ViewEngineResult(
                        (this.CreateView(controllerContext, viewPath, masterPath)), this);
                }
                return new ViewEngineResult(
                  searchedViewLocations.Union<string>(searchedMasterLocations));
            }
            catch (Exception e1)
            {
                WebLogger.WriteToFile("throwing " + e1.Message);
                throw;
            }
        }

      

        private string GetMobileViewPath(string[] locations, string viewName,
                       string controllerName, out string[] searchedLocations)
        {
            string path = null;

            searchedLocations = new string[locations.Length];

            for (int i = 0; i < locations.Length; i++)
            {
                path = string.Format(CultureInfo.InvariantCulture, locations[i],
                                     new object[] { "Mobile/" + viewName, controllerName });
                if (this.VirtualPathProvider.FileExists(path))
                {
                    searchedLocations = new string[0];
                    return path;
                }
                searchedLocations[i] = path;
            }
            return null;
        }
        public override ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
        {
            if (controllerContext == null)
            {
                throw new ArgumentNullException("controllerContext");
            }
            if (string.IsNullOrEmpty(partialViewName))
            {
                throw new ArgumentException("Value is required.", partialViewName);
            }

            string themeName = this.GetThemeToUse(controllerContext);

            string[] searchedLocations=null;

            string controllerName = controllerContext.RouteData.GetRequiredString("controller");

            string partialPath=null;
            if (controllerContext.HttpContext.Request.Browser.IsMobileDevice)
            {
                partialPath = this.GetMobileViewPath(this.PartialViewLocationFormats,
                                    partialViewName, controllerName, out searchedLocations);
            }
            if (partialPath == null)
            {
                partialPath = this.GetViewPath(this.PartialViewLocationFormats,
                                     partialViewName, controllerName, out searchedLocations);
            }

            if (string.IsNullOrEmpty(partialPath))
            {
                return new ViewEngineResult(searchedLocations);
            }
            return new ViewEngineResult(this.CreatePartialView(controllerContext,
                                        partialPath), this);
        }

        private string GetThemeToUse(ControllerContext controllerContext)
        {
            /* if (controllerContext.HttpContext.Request.QueryString.AllKeys.Contains("theme"))
             {
                 string themeName = controllerContext.HttpContext.Request.QueryString["theme"];
                 controllerContext.HttpContext.Session.Add("Theme", themeName);
             }
             else*/
            try
            {
                return ((PersonalAlbumModel)controllerContext.Controller.ViewData.Model).Configuration.ThemePath;
            }
            catch
            {
                //should happen
                return "Default";
            }
        }

        private string GetViewPath(string[] locations, string viewName,
                       string controllerName, out string[] searchedLocations)
        {
            string path = null;

            searchedLocations = new string[locations.Length];

            for (int i = 0; i < locations.Length; i++)
            {
                path = string.Format(CultureInfo.InvariantCulture, locations[i],
                                     new object[] { viewName, controllerName });
                if (this.VirtualPathProvider.FileExists(path))
                {
                    searchedLocations = new string[0];
                    return path;
                }
                searchedLocations[i] = path;
            }
            return null;
        }

        private string GetMasterPath(string[] locations, string viewName,
                       string controllerName, string themeName, out string[] searchedLocations)
        {
            string path = null;

            searchedLocations = new string[locations.Length];

            for (int i = 0; i < locations.Length; i++)
            {
                path = string.Format(CultureInfo.InvariantCulture, locations[i],
                                     new object[] { viewName, controllerName, themeName });
                if (this.VirtualPathProvider.FileExists(path))
                {
                    searchedLocations = new string[0];
                    return path;
                }
                searchedLocations[i] = path;
            }
            return null;
        }
    }
}
